﻿//-----------------------------------------------------------------------
// <copyright file="TupleIndexerEvaluationRecord.cs" company="tuliprules.org">
//     Copyright (c) 2010 tuplelister, tuliprules.org.
// </copyright>
// <summary>This is the TupleIndexerEvaluationRecord class.</summary>
//-----------------------------------------------------------------------

namespace Tulip.Engine.Tuples
{
#pragma warning disable 1587
    /// <summary>
    /// Struct record that relates a tuple indexer and a tuple view delegate.
    /// </summary>
    /// <typeparam name="TTuple">Type of tuple to be evaluated.</typeparam>
#if MONO201_COMPLIANT
    public struct TupleIndexerEvalRec<TTuple>
#else
    public struct TupleIndexerEvaluationRecord<TTuple> where TTuple : Tuple
#endif
#pragma warning restore 1587
    {
        /// <summary>
        /// Delegate that evaluates a rule set of the given tuple type.
        /// </summary>
        public Evaluate<TTuple> EvaluateTuple;

        /// <summary>
        /// Delegate that creates a strongly-typed tuple view for the field indexed by the tuple indexer.
        /// </summary>
        public TupleViewFactory CreateTupleView;

        /// <summary>
        /// Initializes a new instance of the TupleIndexerEvaluationRecord struct.
        /// </summary>
        /// <param name="evaluateTuple">Delegate that evaluates a rule set of the given tuple type.</param>
        /// <param name="createTupleView">Delegate that creates a strongly-typed tuple view for the field indexed by the tuple indexer.</param>
        public TupleIndexerEvaluationRecord(Evaluate<TTuple> evaluateTuple, TupleViewFactory createTupleView)
        {
            this.EvaluateTuple = evaluateTuple;
            this.CreateTupleView = createTupleView;
        }

        /// <summary>
        /// Equlity operator.
        /// </summary>
        /// <param name="record1">The first tuple indexer eval record.</param>
        /// <param name="record2">The second tuple indexer eval record.</param>
        /// <returns>True or false, representing equality.</returns>
        public static bool operator ==(TupleIndexerEvaluationRecord<TTuple> record1, TupleIndexerEvaluationRecord<TTuple> record2)
        {
            return record1.Equals(record2);
        }

        /// <summary>
        /// Inequality operator.
        /// </summary>
        /// <param name="record1">The first tuple indexer eval record.</param>
        /// <param name="record2">The second tuple indexer eval record.</param>
        /// <returns>True or false, representing inequality.</returns>
        public static bool operator !=(TupleIndexerEvaluationRecord<TTuple> record1, TupleIndexerEvaluationRecord<TTuple> record2)
        {
            return !record1.Equals(record2);
        }
        
        /// <summary>
        /// Returns a hash code for the TupleIndexerEvalRec.
        /// </summary>
        /// <returns>A hash code for the TupleIndexerEvalRec.</returns>
        public override int GetHashCode()
        {
            return this.EvaluateTuple.GetHashCode() ^ this.CreateTupleView.GetHashCode();
        }

        /// <summary>
        /// Tests this record against another record to find equality.
        /// </summary>
        /// <param name="obj">The other tuple indexer eval record.</param>
        /// <returns>True or false, representing equality.</returns>
        public override bool Equals(object obj)
        {
            if (!(obj is TupleIndexerEvaluationRecord<TTuple>))
            {
                return false;
            }

            return this.Equals((TupleIndexerEvaluationRecord<TTuple>)obj);
        }

        /// <summary>
        /// Tests this record against another record to find equality.
        /// </summary>
        /// <param name="other">The other tuple indexer eval record.</param>
        /// <returns>True or false, representing equality.</returns>
        public bool Equals(TupleIndexerEvaluationRecord<TTuple> other)
        {
            if (this.CreateTupleView != other.CreateTupleView)
            {
                return false;
            }

            return this.EvaluateTuple == other.EvaluateTuple;
        }
    }
}
